package com.dayu.springbootai.controller;

import com.dayu.springbootai.repository.ChatHistoryRepository;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;

/**
 * 聊天控制器
 * 处理用户与AI模型的交互请求
 * 提供同步和流式两种聊天方式
 * 
 * @author dayu
 * @create 2025-04-06 16:28
 */
@RequestMapping("/ai")
@RestController
public class ChatController {
    /**
     * 注入聊天客户端，用于与AI模型通信
     */
    @Resource
    private ChatClient chatClient;
    
    /**
     * 注入聊天历史仓库，用于保存聊天记录
     */
    @Resource
    ChatHistoryRepository chatHistoryRepository;
    
    /**
     * 同步聊天接口
     * 用户发送问题并等待AI模型完整回复
     * 
     * @param prompt 用户输入的问题
     * @param chatId 会话ID，用于区分不同对话并保存对话历史
     * @return AI模型的回复内容
     */
    @RequestMapping("/chat")
    public String chat(@RequestParam("prompt") String prompt, @RequestParam("chatId") String chatId){
        // 保存会话ID到聊天历史仓库中
        chatHistoryRepository.save("chat", chatId);
        
        // 构建聊天请求并发送
        String msg = chatClient.prompt()
                // 设置用户消息内容
                .user(prompt)
                // 配置对话内存顾问，传入会话ID以维护对话上下文
                .advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId))
                // 发送请求并获取响应
                .call()
                // 提取响应内容
                .content();
        return msg;
    }
    
    /**
     * 流式聊天接口
     * 用户发送问题，AI模型以流式方式逐步返回回复内容
     * 适用于需要实时显示AI回复的场景
     * 
     * @param content 用户输入的内容
     * @return Flux<String> 流式返回的AI回复内容
     */
    @RequestMapping(value = "/chat/stream", produces = "text/html;charset=UTF-8")
    public Flux<String> chatStream(@RequestParam("content") String content){
        // 构建流式聊天请求并发送
        Flux<String> msg = chatClient.prompt()
                // 设置用户消息内容
                .user(content)
                // 以流式方式发送请求
                .stream()
                // 提取响应内容流
                .content();
        return msg;
    }
}